#*******************************************#
# GInfo 数据、图片、运转信息采集 接口说明 #
#*******************************************#
一、用途
可用于通过非客户端的快递业务数据的直接录入,比如通过移动GPRS通道,使用手持终端进行取件录单、转运、派送签收图片等处理。
一、数据接口约定
1、协议:http
2、接口名称:/cgi-bin/GInfo.dll?EmsTrans
3、接口请求方式:POST,text/xml; charset=gbk
4、POST数据标记定义
0操作,数字0-9,含义:0取件,1转运,2派送,3签收,4超时,5扣关,6错误,7丢失,8退件,9异常
YYYY.MM.DD HH:MM:SS操作时间
GG12345手持终端编号,1-30字符
CGG553客户帐号1-15字符
13916365333客户短信号码0-22字符
EM66232332运单号:8-30字母数字或者连字符-
EM66232332转单号:8-30字母数字或者连字符-
EM66232332参考号:8-30字母数字或者连字符-,该号码回传
TNT快递类别,渠道:0-15字符,与系统设置对应
- 1
件数,数字
0包裹类型,数字:0文件,1包裹,2防水袋
2.345重量公斤,三位小数精度
0运费付款方式,数字:0月结,1现付,2到付
PP结算指示,0-3字符:PP,CC,COD,PD
3.54运费,两位小数精度
电视机物品名称,0-254字符
23.45代收货款,两位小数精度
出发地0-63字符
目的地1-63字符,可以使用EMMis能够识别的编码,有编码,电话区号等,条件是与快递类别绑定过
标签0-15字符
签收人0-30字符
备注0-254字符
JPG3字符,大写:BMP,JPG,GIF,PNG
图片数据base64编码
ac003b5fac003b5fac003b5fac003b5f
*任何请求,、、、、为必须的字段,除标记外,其它标记的位置顺序随意,注意会影响MD5编码
*如果OP值为3(签收),必须有标记字段
*标记为最后一个标记,其值为前面的内容附加上密钥后的MD5编码的16进制字串,特别注意,密钥前面的字符一定为“>”,回车换行符将被清除,编码时要注意!
5、返回数据定义:格式文本:返回码\r\n参考号
返回码为一整数,参考号为信息回传,按照标记定义
所有小于零的返回码均表示请求失败,大于零的编码为EMMis系统中的记录ID
返回错误码定义:
-1 :用户不存在,手持终端编号对应的系统用户不存在
-2 :客户不存在,客户账号错误,并且系统中没有开设名称为“现金”的散客帐户,作为找不到客户时的替代
-5 :数据错误,提供的数据不完整或者不符合要求
-6 :没有MD5签名数据
-7 :MD5签名校验失败,请注意密钥的统一!
-9 :数据库错误,GInfo平台问题
-10:数据错误
-11:数据错误
-12:数据错误
-13:数据错误
-14:数据错误
-15:数据错误,为3时,必须定义此标记内容
-16:数据不合法,检查格式是否正确:YYYY.MM.DD hh:mm:ss
#-----------------------
上海钮门网络科技有限公司
2008.12.04
**附:C++ HTTP POST 专用请求函数及例子,供参考
//-----------------------
/*
函数:EmsPost:向GInfo平台的数据传送接口发送请求
参数:
pszHost:http服务器的域名或者ip地址
pszApi:接口位置,规定为:/cgi-bin/GInfo.dll?EmsTrans
pszParam:POST数据,标记封装
pszGet :接收缓存,空间不小于1024字节
返回值:pszGet接收的字节数,小于或等于0为失败
pszGet中的数据含义
格式:状态码\r\n参考号
状态码定义如下:
1、小于或者等于0,错误,含义见文档
2、大于零:成功,该数字为EMMis中的记录ID
*/
int EmsPost(const char *pszHost, const char *pszApi, const char *pszParam, char *pszGet)
{
sockaddr_in sin;
SOCKET sock = socket (AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET) return -100;
sin.sin_family = AF_INET;
sin.sin_port = htons( (unsigned short)80);
struct hostent * host_addr = gethostbyname(pszHost);
if(host_addr==NULL)
{
closesocket(sock);
return -103;
}
sin.sin_addr.s_addr = *((int*)*host_addr->h_addr_list) ;
int TimeOut=60000;
if(::setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
closesocket(sock);
return -120;
}
if(::setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
closesocket(sock);
return -120;
}
unsigned long ul = 1;
int ret = ioctlsocket(sock, FIONBIO, (unsigned long*)&ul);
if(ret==SOCKET_ERROR)
{
closesocket(sock);
return -120;
}
//--尝试建立与服务器的连接
connect (sock,(const struct sockaddr *)&sin, sizeof(sockaddr_in) );//MAY ERROR
struct timeval timeout ;
fd_set r;
FD_ZERO(&r);
FD_SET(sock, &r);
timeout.tv_sec = 60;
timeout.tv_usec =0;
ret = select(0, 0, &r, 0, &timeout);
if ( ret <= 0 )
{
::closesocket(sock);
return -120;
}
unsigned long ul1= 0 ;
ret = ioctlsocket(sock, FIONBIO, (unsigned long*)&ul1);
if(ret==SOCKET_ERROR)
{
::closesocket (sock);
return -120;
}
//--与服务器的连接建立成功
//--构造 http 请求头---
char *b,*p;
b = pszGet + 512;
sprintf(b,
"POST %s HTTP/1.0\r\n"
"Accept: */*\r\n"
"Host: %s\r\n"
"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)\r\n"
"Content-Length: %d\r\n"
"Content-Type: text/xml; charset=gbk\r\n\r\n",
pszApi,
pszHost,
strlen(pszParam));
//--发送请求数据
send(sock,b,strlen(b),0);
send(sock,pszParam,strlen(pszParam),0);
//--发送完毕
char * pEnd=pszGet+1023;
p=pszGet;
//-- 获取响应状态行
while(recv(sock, p, 1, 0) > 0 && p < pEnd)
{
if(*p == '\n') break;
p++;
}
*p = '\0';
if( strstr(pszGet,"200") == NULL)
{
closesocket(sock);
return -102;
}
//--获取其它响应头标--
b=p;
while(recv(sock, p, 1, 0) > 0 && p < pEnd)
{
if(*p == '\n')
{
if(p-b < 5) break;
b=p;
}
p++;
}
//--获取响应实体,保存在pszGet中
p=pszGet;
while(recv(sock,p,1,0) > 0 && p < pEnd) p++;
*p = '\0';
closesocket(sock);
return (p-pszGet);
}
//******************************
//****调用例子1、取件数据*******
char szHost[] ="www.test.cn";
char szGet[1024]={0};
char szKey[32]="abcdefg1234567";
char szParam[1024]={0};
strcpy(szParam,
"0\r\n"
"2008.11.04 10:01:01\r\n"
"pd55663444cn\r\n"
"lhgz\r\n"
"PDA000001\r\n"
"PDA000001R\r\n"
"- 2
\r\n"
"0\r\n"
"1.234\r\n"
"0\r\n"
"PP\r\n"
"33.33\r\n"
"电视机\r\n"
"23.45\r\n"
"北京\r\n"
"美国\r\n"
"PDA传输");
char *p = szParam;
p += strlen(p);
strcpy(p,szKey);
char szMD5[36]={0};
MD5((unsigned char *)szParam,strlen(szParam),szMD5);
sprintf(p,
"\r\n%s",
szMD5);
int iLen = EmsPost( szHost,
"/cgi-bin/GInfo.dll?EmsTrans",
szParam,
szGet);
//**** 调用例子1结束*****
//****调用例子2、签收数据(含图片c:\1.jpg)*******
char szHost[] ="www.test.cn";
char szGet[1024]={0};
char szKey[32]="abcdefg1234567";
char szParam[128000]={0};
strcpy(szParam,
"3\r\n"
"2008.11.04 10:01:01\r\n"
"pd55663444cn\r\n"
"lhgz\r\n"
"PDA000001\r\n"
"PDA000001R\r\n"
"- 2
\r\n"
"0\r\n"
"1.234\r\n"
"0\r\n"
"33.33\r\n"
"电视机\r\n"
"23.45\r\n"
"北京\r\n"
"美国\r\n"
"PDA传输\r\n"
"公司盖章\r\n"
"JPG\r\n"
"");
char *p = szParam;
p += strlen(p);
CFile f;
f.Open("c:\\1.jpg",CFile::modeRead);
BYTE buf[64000];
int iLen = f.GetLength();
f.Read(buf,iLen);
f.Close();
unsigned int ioLen=0;
Base64Encode((const char *)buf,iLen,p,120000,&ioLen);
p+= ioLen;
strcpy(p,"");
p += strlen(p);
strcpy(p,szKey);
char szMD5[36]={0};
MD5((unsigned char *)szParam,strlen(szParam),szMD5);
sprintf(p,
"\r\n%s",
szMD5);
iLen = EmsPost( szHost,
"/cgi-bin/GInfo.dll?EmsTrans",
szParam,
szGet);
//**** 调用例子2结束*****